import { LangGraphWorkflow, WorkflowState } from './langgraph-workflow';
import { hydrateAgentPrompts } from './prompt-loader';

export type AnswerStatus = 'loading' | 'complete' | 'fail';

export type ActionLogSectionType = 'think' | 'tool' | 'observation' | 'result' | 'info';

export interface ActionLogSection {
  id: string;
  type: ActionLogSectionType;
  title: string;
  content: string;
  isCollapsed: boolean;
  timestamp?: string;
}

export interface WorkflowMessage {
  type: 'user' | 'bot' | 'action';
  content: string;
  timestamp: string;
  markdown?: boolean;
  action?: any;
  status?: string | AnswerStatus;
  isCollapsed?: boolean;
  component?: 'answer';
  sections?: ActionLogSection[];
}

interface ActionLogEvent {
  actionId: string;
  step: number;
  thought: string;
  observation?: string;
  toolCalls?: any[];
  final?: boolean;
}

export interface LangGraphChatUI {
  // 状态
  isReady: boolean;
  isProcessing: boolean;
  messages: WorkflowMessage[];
  answers: WorkflowMessage[];
  status: string;

  // 方法
  init(): Promise<void>;
  sendMessage(userMessage: string): Promise<void>;
  resetWorkflowUI(): void;
  addMessage(content: string, type: 'user' | 'bot', options?: { markdown?: boolean; timestamp?: Date }): WorkflowMessage;
  createActionGroup(action: any): any;
  toggleActionCollapse(actionId: string): void;
  toggleActionSection(actionId: string, sectionId: string): void;
  updateStatus(message: string): void;
  setApiKey(apiKey: string): void;
  setModel(model: string): void;
  saveConfig(): Promise<void>;

  // 事件回调
  onMessageUpdate?: (messages: any[]) => void;
  onStatusUpdate?: (status: string) => void;
  onAnswerUpdate?: (answers: WorkflowMessage[]) => void;
  onToolsUpdate?: (summary: Array<{ agentId: string; label: string; enabled: boolean; tools: string[] }>) => void;
}

export class LangGraphChatUIImpl implements LangGraphChatUI {
  private workflow: LangGraphWorkflow | null = null;
  private agentConfig: any = null;
  private apiKey = '';
  private modelOverride = '';
  private actionGroups = new Map();
  private currentStreamingAction: any = null;
  private currentAnswerMessage: WorkflowMessage | null = null;

  public isReady = false;
  public isProcessing = false;
  public messages: WorkflowMessage[] = [];
  public answers: WorkflowMessage[] = [];
  public status = '';

  // 事件回调
  public onMessageUpdate?: (messages: any[]) => void;
  public onStatusUpdate?: (status: string) => void;
  public onAnswerUpdate?: (answers: WorkflowMessage[]) => void;
  public onToolsUpdate?: (summary: Array<{ agentId: string; label: string; enabled: boolean; tools: string[] }>) => void;

  constructor() {
    // 初始化欢迎消息
    this.messages = [{
      type: 'bot',
      content: '👋 你好！先在上方配置 OpenRouter API Key，随后就可以和我对话啦。',
      timestamp: this.formatTime(new Date()),
      markdown: true
    }];
  }

  async init(): Promise<void> {
    await this.loadAgentConfig();
    await this.loadUserConfig();
    this.updateStatus(this.isReady ? '助手已就绪，开始聊天吧。' : '请先配置 OpenRouter API Key。');
    this.notifyMessageUpdate();
  }

  async loadAgentConfig(): Promise<void> {
    try {
      const response = await fetch(chrome.runtime.getURL('agents-config.json'));
      const rawConfig = await response.json();
      this.agentConfig = await hydrateAgentPrompts(rawConfig);
      
      // 初始化 LangGraph 工作流
      this.workflow = new LangGraphWorkflow(
        this.agentConfig,
        this.agentConfig.workflow
      );

      await this.workflow.initialize();
      await this.emitToolsSummary();
      if (this.apiKey || this.modelOverride) {
        this.workflow.updateLLMConfig({
          apiKey: this.apiKey,
          modelOverride: this.modelOverride
        });
      }
      
      console.log('[LangGraph] Agent 配置已加载:', this.agentConfig);
    } catch (error) {
    console.error('加载 Agent 配置失败:', error);
    this.updateStatus('加载 Agent 配置失败，请检查扩展资源。');
  }
}

  async loadUserConfig(): Promise<void> {
    const defaults = {
      openrouterConfig: {
        apiKey: '',
        model: ''
      }
    };

    const { openrouterConfig } = await chrome.storage.local.get(defaults);
    this.apiKey = openrouterConfig.apiKey || '';
    this.modelOverride = openrouterConfig.model || '';
    this.isReady = Boolean(this.apiKey);

    if (this.workflow) {
      this.workflow.updateLLMConfig({
        apiKey: this.apiKey,
        modelOverride: this.modelOverride
      });
    }
    
    console.log('[LangGraph] 用户配置已加载', { hasKey: Boolean(this.apiKey), modelOverride: this.modelOverride });
  }

  async saveConfig(): Promise<void> {
    await chrome.storage.local.set({
      openrouterConfig: {
        apiKey: this.apiKey,
        model: this.modelOverride
      }
    });

    if (this.workflow) {
      this.workflow.updateLLMConfig({
        apiKey: this.apiKey,
        modelOverride: this.modelOverride
      });
    }

    this.updateStatus(this.isReady ? '配置已保存，助手可用。' : '已保存，但缺少 API Key，无法调用 LLM。');
    console.log('[LangGraph] 用户配置已保存', { hasKey: Boolean(this.apiKey), modelOverride: this.modelOverride });
    
    if (this.isReady) {
      this.addMessage('✅ OpenRouter 配置完成，现在可以开始对话了。', 'bot');
    }
  }

  setApiKey(apiKey: string): void {
    this.apiKey = apiKey;
    this.isReady = Boolean(apiKey);
    if (this.workflow) {
      this.workflow.updateLLMConfig({
        apiKey: this.apiKey,
        modelOverride: this.modelOverride
      });
    }
  }

  setModel(model: string): void {
    this.modelOverride = model;
    if (this.workflow) {
      this.workflow.updateLLMConfig({
        apiKey: this.apiKey,
        modelOverride: this.modelOverride
      });
    }
  }

  resetWorkflowUI(): void {
    this.workflow?.resetContext();
    this.workflow?.setActionLogCallback();
    this.actionGroups.clear();
    this.currentStreamingAction = null;
    this.currentAnswerMessage = null;
    this.answers = [];

    // 保留欢迎消息，清除其他消息
    this.messages = this.messages.filter(msg => 
      msg.content.includes('👋 你好！先在上方配置 OpenRouter API Key')
    );

    this.notifyMessageUpdate();
  }

  addMessage(content: string, type: 'user' | 'bot', options: { markdown?: boolean; timestamp?: Date } = {}): WorkflowMessage {
    const { markdown = (type === 'bot'), timestamp = new Date() } = options;
    
    const message = {
      type,
      content,
      timestamp: this.formatTime(timestamp),
      markdown
    };
    
    this.messages.push(message);
    this.notifyMessageUpdate();
    return message;
  }

  createActionGroup(action: any): any {
    const actionGoal = action.goal || action.description || '';
    const placeholderSectionId = `${action.action_id}-pending`;
    const actionGroup = {
      status: 'pending',
      timestamp: this.formatTime(new Date()),
      content: actionGoal,
      actionId: action.action_id,
      sections: [] as ActionLogSection[],
      setStatus: (text: string, date: Date, state: string) => {
        const messageIndex = this.messages.findIndex(msg => 
          msg.type === 'action' && msg.action?.action_id === action.action_id
        );
        if (messageIndex !== -1) {
          this.messages[messageIndex].status = state;
          this.messages[messageIndex].timestamp = this.formatTime(date);
          this.notifyMessageUpdate();
        }
      },
      setContent: (content: string, isStreaming = false) => {
        const now = new Date();
        const sectionId = `${action.action_id}-result`;
        actionGroup.removeSection(placeholderSectionId, false);

        const resultSection: ActionLogSection = {
          id: sectionId,
          type: 'result',
          title: '执行结果',
          content,
          isCollapsed: false,
          timestamp: this.formatTime(now)
        };

        if (isStreaming) {
          actionGroup.upsertSection(resultSection, { mergeContent: true });
        } else {
          actionGroup.upsertSection(resultSection);
        }
        actionGroup.updateMessage();
      },
      appendLog: (chunk: string, options: { 
        type?: ActionLogSectionType; 
        title?: string; 
        collapse?: boolean; 
        sectionId?: string; 
        timestamp?: Date; 
      } = {}) => {
        const { 
          type = 'info', 
          title, 
          collapse = type !== 'info' ? true : false, 
          sectionId, 
          timestamp = new Date()
        } = options;

        if (sectionId !== placeholderSectionId) {
          actionGroup.removeSection(placeholderSectionId, false);
        }

        const section: ActionLogSection = {
          id: sectionId || `${action.action_id}-${type}-${actionGroup.sections.length + 1}-${timestamp.getTime()}`,
          type,
          title: title || actionGroup.generateSectionTitle(type),
          content: chunk,
          isCollapsed: collapse,
          timestamp: this.formatTime(timestamp)
        };

        actionGroup.upsertSection(section);
        actionGroup.updateMessage();
      },
      upsertSection: (section: ActionLogSection, options: { mergeContent?: boolean } = {}) => {
        const idx = actionGroup.sections.findIndex(s => s.id === section.id);
        if (idx !== -1) {
          const existing = actionGroup.sections[idx];
          actionGroup.sections[idx] = {
            ...existing,
            ...section,
            content: options.mergeContent ? existing.content + section.content : section.content,
            timestamp: section.timestamp || existing.timestamp
          };
        } else {
          actionGroup.sections.push(section);
        }
      },
      removeSection: (sectionId: string, update = true) => {
        const idx = actionGroup.sections.findIndex(s => s.id === sectionId);
        if (idx !== -1) {
          actionGroup.sections.splice(idx, 1);
          if (update) {
            actionGroup.updateMessage();
          }
        }
      },
      generateSectionTitle: (type: ActionLogSectionType) => {
        switch (type) {
          case 'think':
            return '思考';
          case 'tool':
            return '工具调用';
          case 'observation':
            return 'Observation';
          case 'result':
            return '执行结果';
          default:
            return '信息';
        }
      },
      updateMessage: () => {
        const messageIndex = this.messages.findIndex(msg => 
          msg.type === 'action' && msg.action?.action_id === action.action_id
        );
        if (messageIndex !== -1) {
          const resultSection = actionGroup.sections.find(section => section.type === 'result');
          this.messages[messageIndex].content = resultSection?.content || '';
          this.messages[messageIndex].sections = actionGroup.sections.map(section => ({ ...section }));
          this.notifyMessageUpdate();
        }
      }
    };

    // 添加action消息
    const actionMessage = {
      type: 'action' as const,
      content: '',
      timestamp: this.formatTime(new Date()),
      action,
      status: 'pending',
      isCollapsed: false,
      sections: [] as ActionLogSection[]
    };

    this.messages.push(actionMessage);
    this.notifyMessageUpdate();

    this.actionGroups.set(action.action_id, actionGroup);
    if (actionGoal) {
      actionGroup.appendLog(`### 任务说明\n${actionGoal}`, {
        type: 'info',
        title: '任务说明',
        collapse: false,
        sectionId: `${action.action_id}-goal`
      });
    }
    actionGroup.appendLog('⌛ 正在执行...', {
      type: 'info',
      title: '执行进度',
      collapse: false,
      sectionId: placeholderSectionId
    });
    return actionGroup;
  }

  toggleActionCollapse(actionId: string): void {
    const messageIndex = this.messages.findIndex(msg => 
      msg.type === 'action' && msg.action?.action_id === actionId
    );
    if (messageIndex !== -1) {
      this.messages[messageIndex].isCollapsed = !this.messages[messageIndex].isCollapsed;
      this.notifyMessageUpdate();
    }
  }

  toggleActionSection(actionId: string, sectionId: string): void {
    const messageIndex = this.messages.findIndex(msg => 
      msg.type === 'action' && msg.action?.action_id === actionId
    );
    if (messageIndex === -1) {
      return;
    }

    const message = this.messages[messageIndex];
    const section = message.sections?.find(item => item.id === sectionId);
    const actionGroup = this.actionGroups.get(actionId);

    if (!section) {
      return;
    }

    section.isCollapsed = !section.isCollapsed;
    if (actionGroup) {
      const groupSection = actionGroup.sections.find(item => item.id === sectionId);
      if (groupSection) {
        groupSection.isCollapsed = section.isCollapsed;
      }
    }

    this.notifyMessageUpdate();
  }

  formatTime(date: Date): string {
    try {
      return date.toLocaleTimeString('zh-CN', {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
      });
    } catch (_) {
      return date.toISOString();
    }
  }

  updateStatus(message: string): void {
    this.status = message;
    this.onStatusUpdate?.(message);
  }

  notifyMessageUpdate(): void {
    this.onMessageUpdate?.(this.messages);
  }

  private createAnswerCard(): WorkflowMessage {
    const message: WorkflowMessage = {
      type: 'bot',
      component: 'answer',
      status: 'loading',
      content: '',
      timestamp: this.formatTime(new Date()),
      markdown: false
    };

    this.answers = [...this.answers, message];
    this.currentAnswerMessage = message;
    this.notifyAnswerUpdate();
    return message;
  }

  private updateAnswerCard(content: string, status?: AnswerStatus) {
    if (!this.currentAnswerMessage) {
      return;
    }

    this.currentAnswerMessage.content = content;
    if (status) {
      this.currentAnswerMessage.status = status;
    }
    this.currentAnswerMessage.timestamp = this.formatTime(new Date());
    this.notifyAnswerUpdate();
  }

  private notifyAnswerUpdate(): void {
    this.onAnswerUpdate?.(this.answers);
  }

  private appendActionLog(event: ActionLogEvent) {
    const actionGroup = this.actionGroups.get(event.actionId);
    if (!actionGroup) {
      return;
    }

    if (event.final) {
      actionGroup.setContent(event.thought, false);
      return;
    }

    const timestamp = new Date();
    const baseStepTitle = `第 ${event.step} 步`;

    if (event.thought?.trim()) {
      actionGroup.appendLog(event.thought.trim(), {
        type: 'think',
        title: `${baseStepTitle} · 思考`,
        collapse: true,
        sectionId: `${event.actionId}-think-${event.step}`,
        timestamp
      });
    }

    if (event.toolCalls?.length) {
      actionGroup.appendLog('```json\n' + JSON.stringify(event.toolCalls, null, 2) + '\n```', {
        type: 'tool',
        title: `${baseStepTitle} · MCP 调用`,
        collapse: true,
        sectionId: `${event.actionId}-tool-${event.step}`,
        timestamp
      });
    }

    if (event.observation) {
      actionGroup.appendLog(event.observation, {
        type: 'observation',
        title: `${baseStepTitle} · Observation`,
        collapse: true,
        sectionId: `${event.actionId}-observation-${event.step}`,
        timestamp
      });
    }
  }

  async sendMessage(userMessage: string): Promise<void> {
    if (!userMessage.trim() || this.isProcessing) {
      return;
    }

    if (!this.isReady) {
      this.addMessage('请先在上方输入有效的 OpenRouter API Key。', 'bot');
      return;
    }

    if (!this.workflow) {
      this.addMessage('工作流未初始化，请重新加载页面。', 'bot');
      return;
    }

    this.resetWorkflowUI();

    // 添加用户消息
    this.addMessage(userMessage, 'user');

    // 准备回答卡片并监听最终输出
    this.createAnswerCard();
    this.updateAnswerCard('', 'loading');
    this.workflow.setActionLogCallback((log) => this.appendActionLog(log));
    this.workflow.setFinalResponseCallback((text, phase) => {
      if (phase === 'fail') {
        this.updateAnswerCard(text || '生成失败，请稍后再试。', 'fail');
        return;
      }

      if (!text && phase !== 'complete') {
        return;
      }

      const status = phase === 'complete' ? 'complete' : 'loading';
      const display = text || (phase === 'complete' ? '（无内容）' : '');
      this.updateAnswerCard(display, status);
    });
    this.isProcessing = true;

    console.log('[LangGraph] 开始处理用户提问:', userMessage);

    try {
      this.updateStatus('正在执行工作流...');
      await this.emitToolsSummary();
      
      // 使用 LangGraph 流式执行
      for await (const stateUpdate of this.workflow.streamExecute(userMessage)) {
        await this.handleStateUpdate(stateUpdate);
      }
      
      this.updateStatus('助手已回复。');
      console.log('[LangGraph] 工作流执行完成');
    } catch (error) {
      console.error('❌ [LangGraph] 工作流执行失败:', error);
      this.addMessage(`❌ 处理失败: ${error.message || '未知错误'}`, 'bot');
      this.updateStatus('处理失败，请检查日志或稍后再试。');
      this.updateAnswerCard(`❌ 处理失败: ${error.message || '未知错误'}`, 'fail');
    } finally {
      this.isProcessing = false;
      this.workflow?.setFinalResponseCallback();
      this.workflow?.setActionLogCallback();
      this.currentAnswerMessage = null;
    }
  }

  private async emitToolsSummary(): Promise<void> {
    if (!this.workflow) {
      return;
    }
    try {
      const summary = await this.workflow.getAgentToolSummary();
      this.onToolsUpdate?.(summary);
    } catch (error) {
      console.warn('[LangGraph] 同步 MCP 工具信息失败:', error);
    }
  }

  private async handleStateUpdate(stateUpdate: Partial<WorkflowState>): Promise<void> {
    // 处理规划阶段
    if (stateUpdate.plan?.actions) {
      this.addMessage(`🧠 规划完成，共 ${stateUpdate.plan.actions.length} 个动作。`, 'bot');
      
      // 显示动作列表
      const actionListMessage = this.createActionListMessage(stateUpdate.plan.actions);
      this.messages.push(actionListMessage);
      this.notifyMessageUpdate();

      // 为每个动作创建 action group
      for (const action of stateUpdate.plan.actions) {
        const actionGroup = this.createActionGroup(action);
        actionGroup.setStatus('执行中', new Date(), 'active');
      }
    }

    // 处理执行结果
    if (stateUpdate.executorOutputs) {
      for (const output of stateUpdate.executorOutputs) {
        const actionGroup = this.actionGroups.get(output.action_id);
        if (actionGroup) {
          if (output.success) {
            actionGroup.setStatus('已完成', new Date(), 'completed');
            actionGroup.setContent(this.formatExecutorResult(output));
          } else {
            actionGroup.setStatus('执行失败', new Date(), 'failed');
            actionGroup.setContent(`❌ ${output.error || '执行失败'}`);
          }
        }
      }
    }

    // 处理最终响应
    if (stateUpdate.finalResponse) {
      if (!this.answers.length) {
        this.addMessage(stateUpdate.finalResponse, 'bot', { markdown: true });
      }
    }

    // 处理错误
    if (stateUpdate.error) {
      this.addMessage(`❌ ${stateUpdate.error}`, 'bot');
    }
  }

  private createActionListMessage(actions: any[]): WorkflowMessage {
    let actionListHtml = '📋 **执行计划：**\n\n';
    actions.forEach((action, index) => {
      actionListHtml += `${index + 1}. **${action.action_id}** · ${action.executor_id || action.agent_id}\n`;
      actionListHtml += `   ${action.description || action.goal || ''}\n\n`;
    });
    
    return {
      type: 'bot',
      content: actionListHtml,
      timestamp: this.formatTime(new Date()),
      markdown: true
    };
  }

  private formatExecutorResult(output: any): string {
    const status = output.success === false ? '❌' : '✅';
    const summary = output.result?.data || output.result?.insights || output.result;
    const statusLine = `${status} 动作 ${output.action_id} 结果：`;

    if (typeof summary === 'string') {
      const trimmed = summary.trim();
      const [primary] = trimmed.split('\n## 工具执行结果');
      const mainContent = primary?.trim() || '';

      if (!mainContent) {
        return statusLine;
      }

      if (mainContent.startsWith('```')) {
        return `${statusLine}\n\n${mainContent}`;
      }

      return `${statusLine}\n\n${mainContent}`;
    }

    try {
      const formatted = JSON.stringify(summary, null, 2);
      return `${statusLine}\n\n` + '```json\n' + `${formatted}\n` + '```';
    } catch (error) {
      console.warn('[LangGraph] 无法序列化执行结果:', error);
      return `${statusLine}\n\n${String(summary)}`;
    }
  }
}
